10231

51 分钟

#C 语言标准库头文件 stdatomic.h

这个头文件提供 原子操作 的相关功能。原子操作是指在并发环境中,一个不可分割的操作,它要么完全执行完毕,要么完全不执行,不会出现执行到一半被其他线程或进程打断的情况。

#示例

#include <stdio.h> #include <stdatomic.h> #include <threads.h> // C11 多线程标准头文件 atomic_int counter = 0; // 计数器,原子类型 // 线程函数,增加计数器 int increment(void* arg) { int loops = *(int*)arg; for (int i = 0; i < loops; i++) { // 原子操作-加一 atomic_fetch_add(&counter, 1); } return 0; } int main(void) { // 原子操作-比较交换:如果 counter 等于 expected,则将 counter 设为 10 int expected = 0; if (atomic_compare_exchange_strong(&counter, &expected, 10)) { printf("counter 的值是 0, 现在将其设为 10\n"); } // 创建多个线程 thrd_t t1, t2; int loops = 100000; thrd_create(&t1, increment, &loops); thrd_create(&t2, increment, &loops); // 等待线程结束 thrd_join(t1, NULL); thrd_join(t2, NULL); printf("最终 counter 的值是: %d\n", atomic_load(&counter)); return 0; }

运行结果:

counter 的值是 0, 现在将其设为 10
最终 counter 的值是: 200010

#类型

类型标准说明
atomic_flagC11一个特殊的原子布尔类型,保证无锁但不提供加载或存储操
memory_orderC11内存顺序 的枚举

#

标准说明
ATOMIC_BOOL_LOCK_FREEC11表示 atomic_bool 类型的原子操作是否是无锁的,0 表示不是无锁,1 表示有时无锁,2表示始终无锁,下同
ATOMIC_CHAR_LOCK_FREEC11表示 atomic_char 类型的原子操作是否是无锁的
ATOMIC_CHAR8_T_LOCK_FREEC23表示 atomic_char8_t 类型的原子操作是否是无锁的
ATOMIC_CHAR16_T_LOCK_FREEC11表示 atomic_char16_t 类型的原子操作是否是无锁的
ATOMIC_CHAR32_T_LOCK_FREEC11表示 atomic_char32_t 类型的原子操作是否是无锁的
ATOMIC_WCHAR_T_LOCK_FREEC11表示 atomic_wchar_t 类型的原子操作是否是无锁的
ATOMIC_SHORT_LOCK_FREEC11表示 atomic_short 类型的原子操作是否是无锁的
ATOMIC_INT_LOCK_FREEC11表示 atomic_int 类型的原子操作是否是无锁的
ATOMIC_LONG_LOCK_FREEC11表示 atomic_long 类型的原子操作是否是无锁的
ATOMIC_LLONG_LOCK_FREEC11表示 atomic_llong 类型的原子操作是否是无锁的
ATOMIC_POINTER_LOCK_FREEC11表示指针类型的原子操作是否是无锁的

#函数

函数标准说明
atomic_initC11初始化一个原子对象,并指定 内存顺序
ATOMIC_VAR_INITC11(在 C17 废弃)初始化一个原子变量,实际上直接赋值即可
ATOMIC_FLAG_INITC11初始化一个 atomic_flag
kill_dependencyC11通知编译器 memory_order_consume 的原子操作不依赖某个值
atomic_thread_fenceC11在当前线程插入一个 内存顺序 屏障
atomic_signal_fenceC11在当前线程和信号处理程序之间插入一个 内存顺序 屏障
原子操作标准说明
atomic_is_lock_freeC11判断对象是否是无锁的
atomic_storeC11原子地将值存入对象
atomic_loadC11原子地读取对象
atomic_exchangeC11原子地将值与对象交换
atomic_compare_exchange_weakC11原子地将值 A 与对象比较,如果相等则将值 B 与对象交换,可能虚假地失败,速度更快,常用于循环中
atomic_compare_exchange_strongC11原子地将值 A 与对象比较,如果相等则将值 B 与对象交换
atomic_fetch_addC11原子加法
atomic_fetch_subC11原子减法
atomic_fetch_orC11原子地按位或
atomic_fetch_xorC11原子地按位异或
atomic_fetch_andC11原子地按位且
atomic_flag_test_and_setC11原子地将 atomic_flag 设为 true 并返回旧值
atomic_flag_clearC11原子地将 atomic_flag 设为 false
指定内存顺序的原子操作标准说明
atomic_store_explicitC11原子地将值存入对象
atomic_load_explicitC11原子地读取对象
atomic_exchange_explicitC11原子地将值与对象交换
atomic_compare_exchange_weak_explicitC11原子地将值 A 与对象比较,如果相等则将值 B 与对象交换,可能虚假地失败,速度更快,常用于循环中
atomic_compare_exchange_strong_explicitC11原子地将值 A 与对象比较,如果相等则将值 B 与对象交换
atomic_fetch_add_explicitC11原子加法
atomic_fetch_sub_explicitC11原子减法
atomic_fetch_or_explicitC11原子地按位或
atomic_fetch_xor_explicitC11原子地按位异或
atomic_fetch_and_explicitC11原子地按位且
atomic_flag_test_and_set_explicitC11原子地将 atomic_flag 设为 true 并返回旧值
atomic_flag_clear_explicitC11原子地将 atomic_flag 设为 false

#内存顺序

内存顺序指定了原子操作如何影响其他线程的内存访问顺序。

内存顺序标准说明
memory_order_relaxedC11仅保证本次操作的原子性,对其它内存操作没有约束
memory_order_consumeC11(在 C++ 26 废弃)仅保证数据依赖的顺序;通常退化为 memory_order_acquire
memory_order_acquireC11保证读取当前原子变量之后的操作不会被重排到前面
memory_order_releaseC11保证写入当前原子变量之前的操作不会被重排到后面
memory_order_acq_relC11组合 memory_order_acquirememory_order_release
memory_order_seq_cstC11一切按顺序执行,通常最慢,但最简单安全

#推荐阅读

创建于 2025/6/14

更新于 2025/6/30